package com.basker.pisces.web.utils;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.basker.pisces.service.constant.ServiceConstants;
import com.basker.pisces.service.exception.MessageHeaderNotFoundException;
import com.basker.pisces.trace.Span;

/**
 * 针对Http请求的工具类
 *
 * @author hangwen
 */
public class RequestUtils {

    /**
     * 从消息头中获取指定参数的值
     *
     * @param request
     * @param name
     * @param required 当前参数否是必须的，如果是，但当前消息头没有参数，那么会抛出异常
     * @return
     */
    public static String getHeader(HttpServletRequest request, String name, boolean required) {
        if (request == null) {
            request = getRequestFormContextHodler();
        }

        Assert.notNull(request, "parameter 'request' is required");
        Assert.hasText(name, "parameter 'name' is required");

        String val = request.getHeader(name);

        if (StringUtils.isEmpty(val) && required) {
            throw new MessageHeaderNotFoundException(name);
        }

        return val;
    }

    /**
     * 从消息头中获取指定参数的值
     *
     * @param name
     * @param required 当前参数否是必须的，如果是，但当前消息头没有参数，那么会抛出异常
     * @return
     */
    public static String getHeader(String name, boolean required) {
        return getHeader(null, name, required);
    }

    /**
     * 从{@link RequestContextHolder}中获取{@link HttpServletRequest}
     *
     * @return
     */
    public static HttpServletRequest getRequestFormContextHodler() {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();

        if (ra instanceof ServletRequestAttributes) {
            return ((ServletRequestAttributes) ra).getRequest();
        }

        return null;
    }

    /**
     * 从消息头中获取Span对象，如果消息头里没有traceId，那么说明当前链路还没有开启监控
     *
     * @return
     */
    public static Span getSpanFromRequest() {
        HttpServletRequest request = RequestUtils.getRequestFormContextHodler();

        String traceId = RequestUtils.getHeader(request, ServiceConstants.MessageHead.TRACE_ID_KEY, false);
        if (traceId == null) {
            return null;
        }

        String spanId = RequestUtils.getHeader(request, ServiceConstants.MessageHead.SPAN_ID_KEY, false);
        String parentSpanId = RequestUtils.getHeader(request, ServiceConstants.MessageHead.PARENT_SPAN_ID_KEY, false);

        Span span = new Span();

        span.setTraceId(traceId);
        span.setId(spanId);
        span.setParentId(parentSpanId);

        return span;
    }

}
